﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using mebc;
using mebc.playground;
using mebc.viewer;
using NUnit.Framework;

namespace mebc.playground
{

    [TestFixture]
    public class ToDictTest
    {
        [Test]
        public void Run()
        {
            IFunctionalUnit split = new Split_into_assignments();
            IFunctionalUnit map = new Map_to_KVP();
            IFunctionalUnit build = new Build_dictionary();
            var td = new ToDictionary(split, map, build);

            Dictionary<string, string> dict = null;
            td.OutputPipe += m => dict = (Dictionary<string, string>) m.Value;

            td.InputPipe(new Message<string>("a=1;b=2"));

            Assert.AreEqual(2, dict.Count);
            Assert.AreEqual("1", dict["a"]);

            td.GetMetaData().ShowGraph();
        }
    }

    public class Split_into_assignments : APartOf<string>
    {
        public override void Process(string message)
        {
            Send<IEnumerable<string>>(message.Split(';'));
        }
    }

    public class Map_to_KVP : APartOf<IEnumerable<string>>
    {
        public override void Process(IEnumerable<string> assignments)
        {
            Console.WriteLine("map");
            Send(
                assignments.Select(a =>
                                       {
                                           var parts = a.Split('=');
                                           return new KeyValuePair<string, string>(parts[0], parts[1]);
                                       })
                );
        }
    }

    public class Build_dictionary : APartOf<IEnumerable<KeyValuePair<string, string>>>
    {
        public override void Process(IEnumerable<KeyValuePair<string, string>> kvps)
        {
            Console.WriteLine("build");
            Send(
                kvps.Aggregate(new Dictionary<string, string>(), (dict, kvp) =>
                                                                     {
                                                                         dict.Add(kvp.Key, kvp.Value);
                                                                         return dict;
                                                                     })
                );
        }
    }

    public class ToDictionary : Board
    {
        public ToDictionary(IFunctionalUnit split, IFunctionalUnit map, IFunctionalUnit build)
        {
            RedirectInputTo<string>(split);
            WireFromTo<IEnumerable<string>>(split, map);
            WireFromTo<IEnumerable<KeyValuePair<string, string>>>(map, build);
            CaptureOutputFrom<Dictionary<string, string>>(build);
        }
    }
}
